package com.test.mybatis.generator;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.junit.Test;

public class CodeCommentGenerator2 {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		codeDing();
        daoXml();
        model();
        enumsCode();
	}
	

    //只需要改动这里;
    private static String database = "enterprise_dev";
    private static String className = "com.mysql.jdbc.Driver";

    private static String username = "root";
    private static String password = "Jiajiale5";

    private static String url = "jdbc:mysql://rm-8vb43b03vawbw24k0oo.mysql.zhangbei.rds.aliyuncs.com:3306/" + database + "?serverTimezone=GMT";
    private static List<String> c = new ArrayList<>();

    private static List<String> template = new ArrayList<>();

    private static List<String> model = new ArrayList<>();

    private static List<String> enums = new ArrayList<>();

    private static String daoPath = System.getProperty("user.dir").indexOf("/") == -1 ?
            System.getProperty("user.dir").replace("\\", "/") : System.getProperty("user.dir");



    static {
        //生成模版
        template.add("Controller.text");
        template.add("Service.text");
        //template.add("Manager.text");
        template.add("Mapper.text");
        c.add("report_calculate");
        model.add("entity.text");
       // model.add("QueryReq.text");
       // model.add("QueryResp.text");
       // model.add("Req.text");
        model.add("Condition.text");

       // enums.add("Enum.text");

    }

    private static void enumsCode() throws Exception {
        List<String> cz = new ArrayList<>();
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, username, password);
        DatabaseMetaData metaData = connection.getMetaData();

        //获取数据库下面所有表
        ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

        while (tables.next()) {
            // 列的个数
            int columnCount = tables.getMetaData().getColumnCount();
            // 根据指定列名称获取数据
            String TABLE_NAME = tables.getString("TABLE_NAME");
            if (TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
                continue;
            }
            if (cz.contains(TABLE_NAME)) {
                continue;
            }
            if (!c.isEmpty()) {
                if (!c.contains(TABLE_NAME)) {
                    continue;
                }
            }
            System.out.println(TABLE_NAME);
            cz.add(TABLE_NAME);
            String head = convertName(TABLE_NAME);
            System.out.println(head);
            String h = head.substring(0, 1);
            for (String t : enums){
                FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/enums/"+ t);
                String str = readFile(inputStream);
                str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
                //获取表的所有列
                ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
                StringBuilder property = new StringBuilder();

                while (columns.next()) {

                    String COLUMN_NAME = columns.getString("COLUMN_NAME");
                    if (COLUMN_NAME.equals("yn")) {
                        continue;
                    }
                    String REMARKS = columns.getString("REMARKS");
                    String enumStr[] = REMARKS.split(" ");

                    if (enumStr.length > 1 && REMARKS.contains(":")) {
                        property.append("/** start---") .append(COLUMN_NAME).append("**/");
                        StringBuilder columnsStr = new StringBuilder();
                        for (int i = 1, l = enumStr.length; i < l; i++) {
                            String s = enumStr[i];
                            if (s.trim().equals("") || s.trim().equals("默认")){
                                continue;
                            }
                            System.out.println(REMARKS);
                            String[] d = s.split(":");
                            if(d.length > 1) {
                                columnsStr.append(COLUMN_NAME.toUpperCase(Locale.ROOT)).append(i).append("(\"");
                                columnsStr.append(d[0]).append("\",\"").append(d[1]).append("\"),");
                            }

                        }
                        property.append(columnsStr);

                    }
                }
                str = str.replace("${property}", property.substring(0, property.length() - 1) + ";");
                System.out.println(str);
                writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + "Enum.java", "enums");
            }

        }
    }

    private static void model() throws Exception {
        List<String> cz = new ArrayList<>();
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, username, password);
        DatabaseMetaData metaData = connection.getMetaData();

        //获取数据库下面所有表
        ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

        while (tables.next()) {
            // 列的个数
            int columnCount = tables.getMetaData().getColumnCount();
            // 根据指定列名称获取数据
            String TABLE_NAME = tables.getString("TABLE_NAME");
            if(TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
                continue;
            }
            if (cz.contains(TABLE_NAME)) {
                continue;
            }
            if (!c.isEmpty()) {
                if (!c.contains(TABLE_NAME)) {
                    continue;
                }
            }
            System.out.println(TABLE_NAME);
            cz.add(TABLE_NAME);
            String head = convertName(TABLE_NAME);
            System.out.println(head);
            String h = head.substring(0, 1);
            for (String t : model){
                String[] ff = t.split("\\.");
                FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/model/"+ t);
                String str = readFile(inputStream);
                str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
                //获取表的所有列
                ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
                StringBuilder property = new StringBuilder();

                while (columns.next()) {
                    String COLUMN_NAME = columns.getString("COLUMN_NAME");
                    String COLUMN_NAME_UP = convertName(COLUMN_NAME);
                    String TYPE_NAME = columns.getString("TYPE_NAME");

                    String REMARKS = columns.getString("REMARKS");
                    String types = "String ";
                    if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("bigint")) {
                        types = "Long ";
                    } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("tinyint") || TYPE_NAME.toLowerCase(Locale.ROOT).equals("int")
                            || TYPE_NAME.toLowerCase(Locale.ROOT).equals("bit")) {
                        types = "Integer ";
                    } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("datetime")) {
                        types = "Date ";
                    } else if (TYPE_NAME.toLowerCase(Locale.ROOT).equals("decimal")) {
                        types = "BigDecimal ";
                    }
                    if (ff[0].equals("Condition")) {
                        if (!COLUMN_NAME_UP.equals("created") && !COLUMN_NAME_UP.equals("createUserId") &&
                                !COLUMN_NAME_UP.equals("createUserName") && !COLUMN_NAME_UP.equals("modified") &&
                                !COLUMN_NAME_UP.equals("modificationUserId") && !COLUMN_NAME_UP.equals("modificationUserName")
                                && !COLUMN_NAME_UP.equals("yn")
                        ) {
                            property.append("    ").append("/** ")
                                    .append("\r\n")
                                    .append("    ").append("*").append(" ").append(REMARKS)
                                    .append("\r\n")
                                    .append("    ").append("**/")
                                    .append("\r\n")
                                    .append("    ").append("private ").append(types).append(COLUMN_NAME_UP).append(";");

                        }
                    } else {
                        property.append("    ").append("/** ")
                                .append("\r\n")
                                .append("    ").append("*").append(" ").append(REMARKS)
                                .append("\r\n")
                                .append("    ").append("**/")
                                .append("\r\n")
                                .append("    ").append("private ").append(types).append(COLUMN_NAME_UP).append(";");
                    }
                    property.append("\r\n");
                    property.append("\r\n");
                }
                str = str.replace("${property}", property.toString());
                System.out.println(str);
                String hh = "";
                if (!ff[0].equals("entity")) {
                    hh = ff[0];
                }
                writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + hh + ".java", "model");
            }

        }

    }


    public static void codeDing() throws Exception {
        List<String> cz = new ArrayList<>();
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, username, password);
        DatabaseMetaData metaData = connection.getMetaData();

        //获取数据库下面所有表
        ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

        while (tables.next()) {
            // 列的个数
            int columnCount = tables.getMetaData().getColumnCount();
            // 根据指定列名称获取数据
            String TABLE_NAME = tables.getString("TABLE_NAME");
            String REMARKS = tables.getString("REMARKS");
            if(TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
                continue;
            }
            if (cz.contains(TABLE_NAME)) {
                continue;
            }
            if (!c.isEmpty()) {
                if (!c.contains(TABLE_NAME)) {
                    continue;
                }
            }
            System.out.println(TABLE_NAME);
            cz.add(TABLE_NAME);
            String head = convertName(TABLE_NAME);
            System.out.println(head);
            String h = head.substring(0, 1);

            for (String t : template) {
                String[] ff = t.split("\\.");
                FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/template/" + t);
                String str = readFile(inputStream);
                str = str.replace("${table}", head);
                str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
                str = str.replace("${remark}", REMARKS);
                System.out.println(str);
                writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + ff[0] + ".java", ff[0].toLowerCase(Locale.ROOT));
            }
        }

    }

    private static void writeFile(String str, String fileName, String dir) {
        String filePath = daoPath + "/src/test/java/com/test/mybatis/generator/file/" + dir + "/";
        FileWriter fw = null;
        try {

            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
            File file2 = new File(filePath + fileName);

            if(!file2.exists()){
                file.createNewFile();
            }
            fw = new FileWriter(filePath + fileName);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(str);
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fw.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    private static String readFile(FileInputStream inputStream) throws IOException {

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        StringBuilder returnStr = new StringBuilder();

        String str = null;
        while ((str = bufferedReader.readLine()) != null) {
            returnStr.append(str);
            returnStr.append("\r\n");
        }
        inputStream.close();
        bufferedReader.close();

        return returnStr.toString();
    }

    private static String convertName(String columnName) {
        StringBuilder sb = new StringBuilder();
        String[] str = columnName.split("_");
        sb.append(str[0]);
        for (int i = 1, l = str.length; i < l; i++) {
            String s = str[i];
            sb.append(s.substring(0, 1).toUpperCase(Locale.ROOT));
            sb.append(s.substring(1));
        }
        return sb.toString();
    }

    public static void daoXml() throws Exception {
        List<String> cz = new ArrayList<>();
        Class.forName(className);
        Connection connection = DriverManager.getConnection(url, username, password);
        DatabaseMetaData metaData = connection.getMetaData();

        //获取数据库下面所有表
        ResultSet tables = metaData.getTables(database, null, "%", new String[]{"TABLE"});

        while (tables.next()) {
            // 列的个数
            int columnCount = tables.getMetaData().getColumnCount();
            // 根据指定列名称获取数据
            String TABLE_NAME = tables.getString("TABLE_NAME");
            if(TABLE_NAME.startsWith("2_") || TABLE_NAME.startsWith("3_")) {
                continue;
            }
            if (cz.contains(TABLE_NAME)) {
                continue;
            }
            if (!c.isEmpty()) {
                if (!c.contains(TABLE_NAME)) {
                    continue;
                }
            }

            System.out.println(TABLE_NAME);
            cz.add(TABLE_NAME);
            String head = convertName(TABLE_NAME);
            System.out.println(head);
            String h = head.substring(0, 1);

            FileInputStream inputStream = new FileInputStream(daoPath + "/src/test/java/com/test/mybatis/generator/xml/dao.text");
            String str = readFile(inputStream);
            str = str.replace("${table}", TABLE_NAME);
            str = str.replace("${Table}", h.toUpperCase(Locale.ROOT) + head.substring(1));
            //获取表的所有列
            ResultSet columns = metaData.getColumns(database, "%", TABLE_NAME, "%");
            StringBuilder map = new StringBuilder();
            StringBuilder columnSql =new StringBuilder();
            StringBuilder valueSql= new StringBuilder();
            StringBuilder setSql =new StringBuilder();
            while (columns.next()) {
                String COLUMN_NAME = columns.getString("COLUMN_NAME");
                String COLUMN_NAME_UP = convertName(COLUMN_NAME);
                String TYPE_NAME = columns.getString("TYPE_NAME");
                columnSql.append(",`").append(COLUMN_NAME).append("`");
                if (COLUMN_NAME.equals("modified") || COLUMN_NAME.equals("created")) {
                    valueSql.append(",now()");
                } else {
                    valueSql.append(",#{").append(COLUMN_NAME_UP).append("}");
                }
                if (!COLUMN_NAME.equals("created")) {
                    if (COLUMN_NAME.equals("modified")) {
                        setSql.append(",`").append(COLUMN_NAME).append("` = now()");
                    } else {
                        setSql.append(",`").append(COLUMN_NAME).append("` = #{").append(COLUMN_NAME_UP).append("}");
                    }
                }
                String p = TYPE_NAME;
                if ("DATETIME".equals(TYPE_NAME)) {
                    p = "TIMESTAMP";
                } else if ("INT".equals(TYPE_NAME)) {
                    p = "INTEGER";
                }
                map.append("<result column=\"" + COLUMN_NAME +"\" property=\"" + COLUMN_NAME_UP + "\" jdbcType=\""+p+"\" />");
                map.append("\r\n");
                map.append("    ");
            }
            str = str.replace("${map}", map.toString());
            str = str.replace("${columnSql}", columnSql.substring(1));
            str = str.replace("${valueSql}", valueSql.substring(1));
            str = str.replace("${setSql}", setSql.substring(1));
            System.out.println(str);
            writeFile(str, h.toUpperCase(Locale.ROOT) + head.substring(1) + "Mapper.xml", "xml");
        }

    }

}
